#include "execute_task.h"

TaskHandle_t executeHandler;  // 执行任务句柄

// 声明控制函数
void showContrl();     // 显示控制
void alarmContrl();    // 报警控制
void airContrl();      // 空调控制
void curtainContrl();  // 窗帘控制

// 外部数据声明（采集处理后的数据）
extern TargetGatherData targetData;  // 当前环境数据（温度/湿度等）

// 配置数据（包含阈值和控制状态）
THData thData;

/**
 * 执行模块初始化
 * 
 * 初始化执行控制相关的外设，并设置默认阈值参数：
 * 1. 如果配置数据未初始化，设置默认阈值和控制状态
 * 2. 初始化LED、蜂鸣器、OLED等外设
 */
void init_execute() {
    // 检查配置数据是否初始化（未初始化则设置默认值）
    if (thData.state == 0) {
        // 设置默认状态：0000 1111 (所有功能开启)
        thData.state = 15; 
        
        // 设置默认阈值参数
        thData.tempMax = 200;  // 温度上限
        thData.tempMin = -20;  // 温度下限
        thData.humiMax = 200;  // 湿度上限
        thData.humiMin = 20;   // 湿度下限
        thData.sunshine = 100; // 光照阈值
        thData.smoke = 200;    // 烟雾阈值
    }
    
    // 初始化执行控制所需的外设
    ledInit();     // 初始化LED指示灯
    BEEP_Init();   // 初始化蜂鸣器
    OLED_Init();   // 初始化OLED显示屏
}

/**
 * 执行控制任务主函数
 * 
 * 循环执行各控制功能，根据配置状态决定是否执行：
 * 1. 显示控制（OLED显示温湿度）
 * 2. 报警控制（阈值检测和声光报警）
 * 3. 空调控制（预留接口）
 * 4. 窗帘控制（预留接口）
 * 
 * @param param 任务参数（未使用）
 */
void execute_task(void *param) {
    while (1) {
        // 根据配置状态执行相应控制功能
        if (thData.state & 0x01) {  // 检查显示功能是否开启 (bit0)
            showContrl();  // 在OLED上显示温湿度数据
        }
        
        if (thData.state & 0x02) {  // 检查报警功能是否开启 (bit1)
            alarmContrl();  // 执行阈值检测和报警控制
        }
        
        if (thData.state & 0x04) {  // 检查空调控制是否开启 (bit2)
            airContrl();  // 空调控制（预留功能）
        }
        
        if (thData.state & 0x08) {  // 检查窗帘控制是否开启 (bit3)
            curtainContrl();  // 窗帘控制（预留功能）
        }
        
        // 延时10个tick（根据系统配置，通常10-100ms）
        vTaskDelay(10);
    }
}

/**
 * 创建执行控制任务
 * 
 * 初始化执行控制任务：
 * - 任务名称: "execute_task"
 * - 栈大小: 128字
 * - 优先级: 2（中等优先级）
 */
void createExecuteTask() {
    xTaskCreate(
        execute_task,      // 任务函数
        "execute_task",    // 任务名称
        128,               // 栈大小（单位：字）
        NULL,              // 任务参数
        2,                 // 任务优先级
        &executeHandler    // 任务句柄
    );
}

/**
 * 显示控制函数
 * 
 * 在OLED屏幕上显示当前环境数据：
 * 1. 清除屏幕
 * 2. 显示温度和湿度标签
 * 3. 刷新显示实际温湿度数值
 */
void showContrl() {
    // 清屏并显示固定文本
    OLED_Clear();
    OLED_ShowString(0, 0, "Temp:  C", 12);  // 温度标签
    OLED_ShowString(0, 15, "Humi:  %", 12); // 湿度标签
    OLED_Refresh_Gram();  // 刷新显存
    
    // 显示实际数值
    OLED_ShowNum(5*6, 0, targetData.temp, 2, 12);  // 温度值（位置X=30）
    OLED_ShowNum(5*6, 15, targetData.humi, 2, 12); // 湿度值（位置X=30）
    OLED_Refresh_Gram();  // 刷新显存
}

/**
 * 报警控制函数
 * 
 * 根据环境数据与阈值的比较结果执行报警操作：
 * 1. 温度异常：点亮LED1
 * 2. 湿度异常：点亮LED2
 * 3. 烟雾超标：点亮LED3
 * 4. 光照过强：点亮LED4
 * 5. 雨水检测：点亮LED5
 * 6. 任一异常触发蜂鸣器持续报警
 */
void alarmContrl() {
    u8 beepflag = 0;  // 报警标志（0=正常，1=异常）
    
    // 温度阈值检测
    if (targetData.temp < thData.tempMin || targetData.temp > thData.tempMax) {
        LED1 = 0;  // 点亮LED1（低电平有效）
        beepflag = 1;
    } else {
        LED1 = 1;  // 熄灭LED1
    }
    
    // 湿度阈值检测
    if (targetData.humi < thData.humiMin || targetData.humi > thData.humiMax) {
        LED2 = 0;  // 点亮LED2
        beepflag = 1;
    } else {
        LED2 = 1;  // 熄灭LED2
    }
    
    // 烟雾检测
    if (targetData.smoke > thData.smoke) {
        LED3 = 0;  // 点亮LED3
        beepflag = 1;
    } else {
        LED3 = 1;  // 熄灭LED3
    }
    
    // 光照检测
    if (targetData.sunshine > thData.sunshine) {
        LED4 = 0;  // 点亮LED4
        beepflag = 1;
    } else {
        LED4 = 1;  // 熄灭LED4
    }
    
    // 雨水检测（0表示检测到雨水）
    if (!targetData.raidrop) {
        LED5 = 0;  // 点亮LED5
        beepflag = 1;
    } else {
        LED5 = 1;  // 熄灭LED5
    }
    
    // 蜂鸣器控制
    if (!beepflag) {
        BEEP = 1;  // 关闭蜂鸣器（正常状态）
    } else {
        
            BEEP = !BEEP;  // 翻转蜂鸣器状态
            delay_us(20);  // 短暂延时（约20微秒）
        
    }
}

/**
 * 空调控制函数（预留）
 * 
 * 预留的空调控制接口，后续可添加红外控制逻辑
 */
void airContrl() {
    // 待实现：发送红外控制信号
}

/**
 * 窗帘控制函数（预留）
 * 
 * 预留的窗帘控制接口，后续可添加电机控制逻辑
 */
void curtainContrl() {
    // 待实现：控制窗帘电机
}